﻿namespace Pyramid.Hardware.MicroArchitecture
{
    using System.Collections.Generic;
    using System.Linq;
    using Pyramid.Hardware.Gates;

    public class RegisterFile
    {
        public RegisterFile(IEnumerable<ILine> writeBus, IEnumerable<ILine> readSelectorBus, IEnumerable<ILine> writeSelectorBus, ILine writeLine, ILine clock, int registerCount)
        {
            var writeDecoder = new MultilineDecoder(writeSelectorBus);

            var outputBuses = new List<IEnumerable<ILine>>();

            for (int registerIndex = 0; registerIndex < registerCount; registerIndex++)
            {
                var register = new Register(writeBus, clock, new AndGate(writeLine, writeDecoder.OutputBus.ElementAt(registerIndex)));

                outputBuses.Add(register.OutputBus);
            }

            this.OutputBuses = outputBuses;

            var readMultiplexer = new BusMultiplexer(readSelectorBus, OutputBuses);

            this.ReadBus = readMultiplexer.OutputBus;
        }

        public IEnumerable<ILine> ReadBus
        {
            get;
            private set;
        }

        public IEnumerable<IEnumerable<ILine>> OutputBuses
        {
            get;
            private set;
        }
    }
}
